home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 23 / AMIGAplus Sonderheft 23 (2000)(Falke)(DE)[!].iso / Updates / Librarys / MMULib / C_Sources / MuContextTest.c < prev    next >
C/C++ Source or Header  |  1999-06-03  |  13KB  |  360 lines

  1. /*************************************************
  2.  ** MuContextTest                               **
  3.  **                                             **
  4.  ** Build a task with a private context and its **
  5.  ** own page size                               **
  6.  **                                             **
  7.  ** © 1999 THOR-Software                        **
  8.  ** Version 1.01        01.06.1999              **
  9.  *************************************************/
  10.  
  11. /// Includes
  12. #include <exec/types.h>
  13. #include <exec/memory.h>
  14. #include <dos/dos.h>
  15. #include <dos/dostags.h>
  16. #include <dos/dosextens.h>
  17.  
  18. /* MMU specific includes */
  19. #include <mmu/mmutags.h>
  20. #include <mmu/context.h>
  21.  
  22. #include <proto/exec.h>
  23. #include <proto/dos.h>
  24. #include <proto/mmu.h>
  25.  
  26. #include <string.h>
  27. ///
  28. /// Defines
  29.  
  30. /* This is the location we will remap accesses to. Should be
  31.    available on all systems. */
  32. #define TESTLOCATION 0x80000000
  33. ///
  34. /// Protos
  35.  
  36. /* prototyping */
  37.  
  38. long __saveds main(void);
  39. void MMUTaskTest(void);
  40. void RunTests(struct MMUContext *privctx,UBYTE *testpage,UBYTE *pother);
  41. void Sync(struct MsgPort *destination,struct Message *msg);
  42. void __saveds TestProc(void);
  43. ///
  44. /// Statics
  45.  
  46. /* Just the library bases we need */
  47. char version[]="$VER: MuContextTest 1.02 (1.6.99) ©THOR";
  48.  
  49. struct MMUBase *MMUBase;
  50. struct DosLibrary *DOSBase;
  51. struct ExecBase *SysBase;
  52. ///
  53.  
  54. /// main
  55. long __saveds main(void)
  56. {
  57. long err,rc;
  58.  
  59.         /* This program compiles without startup code, hence we have
  60.            to setup ourselfs */
  61.  
  62.         SysBase=*((struct ExecBase **)(4L));
  63.         rc=20;
  64.  
  65.         /* open the required libraries */
  66.  
  67.         if (DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37)) {
  68.  
  69.                 if (MMUBase=(struct MMUBase *)OpenLibrary("mmu.library",0L)) {
  70.  
  71.                         err=ERROR_REQUIRED_ARG_MISSING;
  72.  
  73.                         /* Check for a valid MMU. The mmu.library will also
  74.                            open without! */
  75.  
  76.                         if (!GetMMUType()) {
  77.                                 Printf("MuFastRom requires a working MMU.\n");
  78.                                 err=10;
  79.                         } else {
  80.                                 /* Run the tests */
  81.                                 MMUTaskTest();
  82.                                 err=0;
  83.                         }
  84.  
  85.                         /* Check for error codes. Everything below 64
  86.                            is considered to be a custom error and
  87.                            passed thru as primary result code. */
  88.                         if (err<64) {
  89.                                 rc=err;
  90.                                 err=0;
  91.                         } else {
  92.                                 PrintFault(err,"MuContextTest failed");
  93.                                 rc=10;
  94.                         }
  95.                         SetIoErr(err);
  96.  
  97.                         /* Shut down: Close libraries */
  98.                         CloseLibrary((struct Library *)MMUBase);
  99.                 } else PrintFault(ERROR_OBJECT_NOT_FOUND,"MuContextTest");
  100.                 CloseLibrary((struct Library *)DOSBase);
  101.         }
  102.  
  103.         return rc;
  104. }
  105. ///
  106. /// MMUTaskTest
  107. void MMUTaskTest(void)
  108. {
  109. struct MMUContext *ctx,*privctx;
  110. UBYTE *testpage,*physical;
  111. ULONG size,psize;
  112. ULONG pother=TESTLOCATION;
  113. ULONG error=0;
  114.  
  115.         /* This is the TRUE test, finally. */
  116.  
  117.  
  118.         /* Get the public default context as template for the new
  119.            context */
  120.         Printf("Locating the default context...\n");
  121.         ctx=DefaultContext();
  122.  
  123. /*
  124. #define TL      0x90000000
  125. #define PS      0x00001000
  126.  
  127.         SetProperties(ctx,MAPP_BUNDLED,MAPP_BUNDLED,TL+PS,PS*2,MAPTAG_DESTINATION,TL,TAG_DONE);
  128.         SetProperties(ctx,MAPP_BUNDLED,MAPP_BUNDLED,TL+PS*5,PS*2,MAPTAG_DESTINATION,TL,TAG_DONE);
  129. */
  130.  
  131.         Printf("Building a new context...\n");
  132.         if (privctx=CreateMMUContext(MCXTAG_COPY,ctx,
  133.                 /* make a copy of the already existing context */
  134.                                      MCXTAG_PAGEBITS,13,
  135.                 /* but use 8K pages */
  136.                                      MCXTAG_ERRORCODE,&error,
  137.                 /* and deliver an error code */
  138.                                      TAG_DONE)) {
  139.  
  140.                 /* I don't check here for an error, even though I should.
  141.                    The library will build the context, provided there is
  142.                    enough memory and the parameters are valid for the hard-
  143.                    ware, but "error" should be checked for problems
  144.                    the library found. This is only required if you tried
  145.                    to make a table setup different to the default - here
  146.                    the 8K pages. "error" should be checked for
  147.                    CCERR_UNALIGNED. In this case, the mmu.library had to
  148.                    round some descriptors heavely to be 8K aligned and the
  149.                    resulting page setup is most likely not what you want.
  150.                    For example, MAPP_REMAPPED pages have been trimmed, and
  151.                    the setup is therefore incorrect at the boundary. */
  152.  
  153.                 /* Find out the page size of this page. Well, we know
  154.                    it is 8K, right? */
  155.                 size=GetPageSize(privctx);
  156.                 Printf("Getting the new page size. It is 0x%lx bytes.\n",size);
  157.  
  158.                 /* allocate a test page */
  159.                 testpage=AllocAligned(size,MEMF_PUBLIC,size);
  160.                 if (testpage) {
  161.                         /* Find out the physical location of this page.
  162.                            Note that we use the public context since this
  163.                            is the context we're running in. The other
  164.                            context has not yet been loaded. */
  165.                         physical=testpage;
  166.                         psize=size;
  167.                         Printf("Allocating a test page.\n");
  168.                         PhysicalLocation(ctx,(void **)&physical,&psize);
  169.                         if (psize==size) {
  170.  
  171.                                 /* remap (mirror) it to pother. This is just
  172.                                    for demonstrational purposes. */
  173.                                 Printf("Mirroring the page at 0x%08lx (0x%08lx phys.) to 0x%08lx\n",testpage,physical,pother);
  174.  
  175.                                 if (SetProperties(privctx,MAPP_COPYBACK|MAPP_REMAPPED,~0,
  176.                                                    pother,size,MAPTAG_DESTINATION,physical,TAG_DONE)) {
  177.  
  178.                                         /* the above call modified only the software abstraction
  179.                                            level. Now rebuild the MMU tree for the private
  180.                                            context to reflect the changes */
  181.  
  182.  
  183.                                         Printf("Building a new MMU tree for the private context...\n");
  184.                                         if (RebuildTree(privctx)) {
  185.  
  186.                                                 /* and run the test */
  187.                                                 RunTests(privctx,testpage,(UBYTE *)pother);
  188.                                                 /* all the rest is shutdown code */
  189.  
  190.                                         } else Printf("Can't rebuild the tree.\n");
  191.                                 } else Printf("Failed to setup memory remapping.\n");
  192.                         } else Printf("Can't handle fragmented memory.\n");
  193.  
  194.                         /* release the test page */
  195.  
  196.                         Printf("Releasing the test page.\n");
  197.                         FreeMem(testpage,size);
  198.                 } else Printf("Failed to allocate a test page.\n");
  199.  
  200.                 /* ... and the context */
  201.  
  202.                 Printf("Releasing the private context.\n");
  203.                 DeleteMMUContext(privctx);
  204.  
  205.         } else Printf("Failed to build the MMUTaskTest.\n");
  206.  
  207. }
  208. ///
  209. /// RunTests
  210. void RunTests(struct MMUContext *privctx,UBYTE *testpage,UBYTE *pother)
  211. {
  212. struct Process *proc;
  213. struct Message *msg;
  214. struct Task *testtask,*mytask;
  215. struct MsgPort *testport;
  216. int i;
  217.  
  218.         /* given the MMU context created above, create a new task
  219.            and run it in this context */
  220.  
  221.         /* Build a message with our process port as reply port. I'm here
  222.